package top.conangao.common.security.autoconfig;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.security.oauth2.resource.OAuth2ResourceServerProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.DefaultSecurityFilterChain;
import org.springframework.security.web.SecurityFilterChain;
import top.conangao.common.security.handler.CustomOpaqueTokenIntrospector;
import top.conangao.common.security.util.SecurityUtils;

/**
 * @author ConanGao
 * @description 资源服务器配置
 * @since 1.0
 **/
@Configuration(proxyBeanMethods = false)
@EnableWebSecurity
@EnableMethodSecurity
@ConditionalOnClass(OAuth2ResourceServerProperties.class)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@Slf4j
public class ResourceServerConfig {
    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE + 1000)
    @ConditionalOnMissingBean(name = "defaultSecurityFilterChain")
    public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests(request-> request.requestMatchers("/swagger-ui.html","/swagger-ui/**","/v3/api-docs/**").permitAll().anyRequest().authenticated())
                .oauth2ResourceServer(server ->server
                    .opaqueToken(Customizer.withDefaults())
                    .accessDeniedHandler(SecurityUtils::exceptionHandler)
                    .authenticationEntryPoint(SecurityUtils::exceptionHandler));
        DefaultSecurityFilterChain build = http.build();
        log.info("==========加载默认WebSevlet安全过滤器链成功==========");
        return build;
    }
    
    @Bean
    @Primary
    @ConditionalOnProperty(
            name = {"spring.security.oauth2.resourceserver.opaquetoken.introspection-uri"}
    )
    public CustomOpaqueTokenIntrospector customAuthoritiesOpaqueTokenIntrospector(OAuth2ResourceServerProperties properties){
        OAuth2ResourceServerProperties.Opaquetoken opaqueToken = properties.getOpaquetoken();
        return new CustomOpaqueTokenIntrospector(opaqueToken.getIntrospectionUri(),
                opaqueToken.getClientId(), opaqueToken.getClientSecret());
    }
    
    @Bean
    @ConditionalOnMissingBean
    public PasswordEncoder passwordEncoder(){
        PasswordEncoder delegatingPasswordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
        log.info("==========加载自定义密码加密器成功==========");
        return delegatingPasswordEncoder;
    }

//    @Bean
//    public JwtAuthenticationConverter jwtAuthenticationConverter() {
//        JwtGrantedAuthoritiesConverter grantedAuthoritiesConverter = new JwtGrantedAuthoritiesConverter();
//        // 设置解析权限信息的前缀，设置为空是去掉前缀
//        grantedAuthoritiesConverter.setAuthorityPrefix("");
//        // 设置权限信息在jwt claims中的key
//        grantedAuthoritiesConverter.setAuthoritiesClaimName("authorities");
//
//        JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter();
//        jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(grantedAuthoritiesConverter);
//        return jwtAuthenticationConverter;
//    }
    
}
